package com.lyn.solitude_plugin_host.binder;

import android.app.Application;
import android.content.ComponentName;
import android.content.Intent;
import android.os.RemoteException;
import android.util.Log;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.lyn.solitude_aidl_host.PluginHostAidlInterface;
import com.lyn.solitude_plugin_api.entity.Plugin;
import com.lyn.solitude_plugin_api.file.FileUtil;
import com.lyn.solitude_plugin_api.file.Folder;
import com.lyn.solitude_plugin_api.file.FolderFactory;
import com.lyn.solitude_plugin_host.activity.PluginProxyActivity;
import com.lyn.solitude_plugin_host.builder.ImpBuilder;
import com.lyn.solitude_plugin_host.config.PluginFileConfig;
import com.lyn.solitude_plugin_host.stack.PluginStack;

import java.io.File;
import java.util.Map;
import java.util.concurrent.ConcurrentSkipListMap;

/**
 * @author longyn 2024/5/11
 * @version 1.0.0
 */
public class PluginHostBinder extends PluginHostAidlInterface.Stub {

    private static final String TAG = "PluginHostBinder";

    private static final class PluginHostBinderTypeClass {
        private static final PluginHostBinder in = new PluginHostBinder();
    }

    public static PluginHostBinder getInstance() {
        return PluginHostBinderTypeClass.in;
    }

    private Application application;
    private final Map<String, Plugin> pluginMap = new ConcurrentSkipListMap<>();


    public void initialize(Application application) {
        this.application = application;
        Log.d(TAG, "initialize");
        String rootPath = application.getFilesDir().getAbsolutePath();
        FolderFactory.create(rootPath.concat("/").concat(PluginFileConfig.PLUGIN),
                PluginFileConfig.PLUGIN);
        FolderFactory.create(rootPath.concat("/").concat(PluginFileConfig.SO),
                PluginFileConfig.SO);
        FolderFactory.create(rootPath.concat("/").concat(PluginFileConfig.OPTIMIZED),
                PluginFileConfig.OPTIMIZED);
    }


    @Override
    public String loadAll() throws RemoteException {
        Log.d(TAG, "loadAll");
        JSONArray pluginJSONArray = new JSONArray();
        Folder folder = FolderFactory.getFolder(PluginFileConfig.PLUGIN);
        File[] folderFiles = folder.getFiles();
        pluginMap.clear();
        for (File f : folderFiles) {
            Plugin plugin = new ImpBuilder(application, f.getAbsolutePath()).build();
            if (plugin == null) {
                Log.d(TAG, "build plugin " + f.getName() + " fail");
                continue;
            }
            JSONObject pluginJSONObject = new JSONObject();
            pluginJSONObject.put("id", plugin.id);
            pluginJSONObject.put("name", plugin.name);
            pluginJSONObject.put("version", plugin.version);
            pluginJSONObject.put("path", plugin.path);
            pluginJSONObject.put("soPath", plugin.soPath);
            pluginJSONObject.put("className", plugin.mate.activityClassName);
            pluginJSONArray.add(pluginJSONObject);

            pluginMap.put(plugin.id, plugin);
        }
        return pluginJSONArray.toJSONString();
    }

    @Override
    public int remove(String id) throws RemoteException {
        Log.d(TAG, "remove id:" + id);
        Plugin plugin = pluginMap.get(id);
        if (plugin == null) {
            throw new RemoteException("Plugin == null");
        }
        File pluginFile = new File(plugin.path);
        boolean deletePluginFile = pluginFile.delete();
        Log.d(TAG, "Delete plugin file:" + deletePluginFile);
        FileUtil.deleteFolder(plugin.soPath);

        File soFolderFile = new File(plugin.soPath);
        boolean deleteSoFolder = soFolderFile.delete();
        Log.d(TAG, "Delete plugin so folder:" + deleteSoFolder);

        pluginMap.remove(id);
        return 0;
    }

    @Override
    public int open(String id) throws RemoteException {
        Log.d(TAG, "open id:" + id);
        Plugin plugin = pluginMap.get(id);
        if (plugin == null) {
            throw new RemoteException("plugin == null");
        }
        Intent intent = new Intent();
        ComponentName componentName = new ComponentName(application.getPackageName(), plugin.mate.activityClassName);
        intent.setComponent(componentName);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.putExtra(PluginProxyActivity.PLUGIN_ACTIVITY_CLASS_NAME_KEY, plugin.mate.activityClassName);
        PluginStack.push(plugin);
        application.startActivity(intent);
        return 0;
    }

    @Override
    public int jump(String id, String className) throws RemoteException {
        Log.d(TAG, "jump id:" + id + " className:" + className);
        Plugin plugin = pluginMap.get(id);
        if (plugin == null) {
            throw new RemoteException("plugin == null");
        }
        Intent intent = new Intent();
        ComponentName componentName = new ComponentName(application.getPackageName(), className);
        intent.setComponent(componentName);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.putExtra(PluginProxyActivity.PLUGIN_ACTIVITY_CLASS_NAME_KEY, className);
        PluginStack.push(plugin);
        application.startActivity(intent);
        return 0;
    }
}
